﻿using UnityEngine;
using System.Collections.Generic;
using LuaInterface;
using System;
using SimpleJSON;
using System.Linq;
using FairyGUI;

namespace YanhuaMMO
{
    public class PanelManager : Manager
    {
		enum ViewState
		{
			loading,
			opened,
			closing,
			close,
		}
		private List<ViewStack> viewStackList = new List<ViewStack>();

        private Transform _parent;
        private Transform _topCanvas;
        //private Transform baseParent;
        private Transform _baseTopParent;

        private Transform _mainParent;
        private Transform _mainTopParent;
        private Transform _popParent;
        private Transform _popTopParent;
        private Transform _msgParent;
        private Transform _topParent;

        public GameObject uiDownLoad;
        private Transform _battleMain;
        private Transform _battleRound;
        private Transform _bgFGUICamera;
        private Transform _camMain;
        private Transform _camRound;
        private readonly List<string> _showingList = new List<string>();
        private readonly List<List<string>> _lockList = new List<List<string>>();
        private readonly Dictionary<string, GComponent> _waiting = new Dictionary<string, GComponent>();

        private Canvas _canvas;



        public delegate void LuaDelegate(GComponent go);
        public Dictionary<string, GComponent> UIs = new Dictionary<string, GComponent>();
        public List<string> _deletingUIs = new List<string>();
        private Dictionary<string, string> mUINameToPackageName = new Dictionary<string, string>();
        private readonly List<string> _uiQueue = new List<string>();

        private string _defaultMusic = null;
        public Dictionary<string, int> uiLayerIdx = new Dictionary<string, int>();
        public Dictionary<string, int> uiLayerOpen = new Dictionary<string, int>();
        public bool pauseChangeSound = false;
        public Dictionary<string, GameObject> loadedPanel = new Dictionary<string, GameObject>();
		
        // private List<string> commonUIPackage = new List<string>() {"FUI/EquipItem","FUI/UIBattle","FUI/MainUI","FUI/CommonUI","FUI/UIRedDots","FUI/SkillAtlas","FUI/ICONAtlas", "FUI/ItemAtlas" ,"FUI/BattleItems"};

        private void Awake()
        {
			//Font font = Resources.Load<Font>("Fonts/GoogleSiYuan_Heavy");
			//FontManager.RegisterFont(new DynamicFont("GoogleSiYuan_Heavy", font));
			var tran = BGFGUICameraMain;
			if(tran != null)
				tran.gameObject.SetActive(false);
        }
        public bool isNeedFit
        {
            get
            {
                float height = 0;
#if UNITY_IOS || UNITY_ANDROID
                height = Screen.height - Screen.safeArea.height; //  获取刘海高度
                Debug.Log("fit height == " + height);
#endif
                if (height > 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        public Transform Parent
        {
            get
            {
                if (_parent != null) return _parent;
                var go = GameObject.FindWithTag("GuiCamera");
                if (go != null) _parent = go.transform;

                return _parent;
            }
        }
        public Transform TopCanvas
        {
            get
            {
                if (_topCanvas != null) return _topCanvas;
                var go = GameObject.FindWithTag("topCanvas");
                if (go != null) _topCanvas = go.transform;
                return _topCanvas;
            }
        }

        public Canvas Canvas
        {
            get
            {
                if (_canvas != null) return _canvas;
                _canvas = Parent.parent.GetComponent<Canvas>();
                return _canvas;
            }
        }

        public string[] GetCreateUIList()
        {
            var uiPackages = new List<string>();
            foreach (string uiName in UIs.Keys) 
            {
                string uiPackageName = mUINameToPackageName[uiName];
                uiPackageName = uiPackageName.Replace("FUI/", "");
                uiPackages.Add(uiPackageName + "/" + uiName);
            }
            return uiPackages.ToArray();
        }

        public Transform MainParent
        {
            get
            {
                if (_mainParent != null) return _mainParent;
                _mainParent = Canvas.transform.Find("MainParent");

                return _mainParent;
            }
        }

        public Transform MainTopParent
        {
            get
            {
                if (_mainTopParent != null) return _mainTopParent;
                _mainTopParent = Canvas.transform.Find("MainTopParent");

                return _mainTopParent;
            }
        }

        public Transform PopParent
        {
            get
            {
                if (_popParent != null) return _popParent;
                _popParent = Canvas.transform.Find("PopParent");

                return _popParent;
            }
        }

        public Transform PopTopParent
        {
            get
            {
                if (_popTopParent != null) return _popTopParent;
                _popTopParent = Canvas.transform.Find("PopTopParent");

                return _popTopParent;
            }
        }

        public Transform MsgParent
        {
            get
            {
                if (_msgParent != null) return _msgParent;
                _msgParent = Canvas.transform.Find("MsgParent");

                return _msgParent;
            }
        }


        public Transform TopParent
        {
            get
            {
                if (_topParent != null) return _topParent;
                _topParent = Canvas.transform.Find("TopParent");

                return _topParent;
            }
        }




        public Transform BaseTopParent
        {
            get
            {
                if (_baseTopParent != null) return _baseTopParent;
                _baseTopParent = TopCanvas.Find("BaseTopParent");

                return _baseTopParent;
            }
        }

        public Transform BattleMain
        {
            get
            {
                if (_battleMain != null) return _battleMain;
                var go = GameObject.FindWithTag("BattleMain");
                if (go != null) _battleMain = go.transform;

                return _battleMain;
            }
        }

        public Transform BattleRound
        {
            get
            {
                if (_battleRound != null) return _battleRound;
                var go = GameObject.FindWithTag("BattleRound");
                if (go != null) _battleRound = go.transform;

                return _battleRound;
            }
        }

        public Transform BGFGUICameraMain
        {
            get
            {
                if (_bgFGUICamera != null) return _bgFGUICamera;
                var go = GameObject.FindWithTag("BGFGUICamera");
                if (go != null) _bgFGUICamera = go.transform;

                return _bgFGUICamera;
            }
        }


        public Transform CameraMain
        {
            get
            {
                if (_camMain != null) return _camMain;
                var go = GameObject.FindWithTag("MainCamera");
                if (go != null) _camMain = go.transform;

                return _camMain;
            }
        }

        public Transform CameraRound
        {
            get
            {
                if (_camRound != null) return _camRound;
                var go = GameObject.FindWithTag("CameraRound");
                if (go != null) _camRound = go.transform;

                return _camRound;
            }
        }

        public void Init()
        {
            SetLockList();
            BattleMain.gameObject.SetActive(false);
            BattleRound.gameObject.SetActive(false);
			BGFGUICameraMain.gameObject.SetActive(false);
            Debug.Log("PanelManager:Init");
            InitUILayerIdx();
        }

        private void SetLockList()
        {
            var lockList = LuaHelper.GetLuaManager().CallFunc("GetUILock");
            if (lockList == null || lockList[0] == null) return;
            _lockList.Clear();
            var json = lockList[0].ToString();
            var lockJson = JSON.Parse(json);
            var array = lockJson.AsArray;
            for (var i = 0; i < array.Count; i++)
            {
                var list = new List<string>();
                var node = array[i];
                var lk = node.AsArray;
                for (var j = 0; j < lk.Count; j++)
                {
                    list.Add(lk[j].Value);
                }
                _lockList.Add(list);
            }
        }

        private bool CheckLocked(string name)
        {
            return _lockList.Where(t => t.Contains(name)).Any(t => t.Any(t1 => _showingList.Contains(t1) && UIs.ContainsKey(t1) && UIs[t1].visible == true && t1 != name));
        }
		private ViewStack GetStack(string name)
		{
			for(int i = 0; i < viewStackList.Count; i++)
			{
				if (viewStackList[i].name == name)
					return viewStackList[i];
			}
			return null;
		}
		private void AddStack(ViewStack stack)
		{
			RemoveStack(stack.name);
			viewStackList.Add(stack);
		}
		private void RemoveStack(string name)
		{
			for (int i = 0; i < viewStackList.Count; i++)
			{
				if (viewStackList[i].name == name)
				{
					viewStackList.RemoveAt(i);
					return;
				}
			}
		}
        private void _OpenUI(string name, string package, GComponent obj)
        {
			if (string.IsNullOrEmpty(name) == false && _showingList.Contains(name) == false)
            {
                //Util.CallDisposeMethod("_G", "AddCacheCreateUIAndDestory", package.Replace("FUI/", "") + "/" + name);

                _showingList.Add(name);
                if (CheckLocked(name))
                {

                    // obj.transform.localPosition = new Vector3(10000,0, obj.transform.localPosition.z);
                    if (!_waiting.ContainsKey(name))
                        _waiting.Add(name, obj);
                }

                FairyGUI.Transition openTrans = obj.GetTransition("Effect_JumpOut");
                if (openTrans != null)
                {
					openTrans.invalidateBatchingEveryFrame = true;

					openTrans.Play(() =>
					{
						obj.fairyBatching = true;
					});
				}
				else
				{
					obj.fairyBatching = true;
				}
            }

            if (name == "UILogin") 
            {
                if (GameLoginBefore.Instance) GameLoginBefore.Instance.DelStartGame();
            }

            CheckApexPanel();
        }
        private void _CloseUI(string name, GComponent obj)
        {
            if (string.IsNullOrEmpty(name) || _showingList.Contains(name) != true) return;
            _showingList.Remove(name);
            if (!CheckLocked(name)) return;
            foreach (var t in _lockList.Where(t => t.Contains(name)))
            {
                foreach (var pair in _waiting.Where(pair => pair.Key != name && _showingList.Contains(pair.Key)))
                {
                    if (pair.Value == null || CheckLocked(pair.Key))
                    {
                        Debug.Log("waiting break");
                        break;
                    }

                    // pair.Value.transform.localPosition = new Vector3(0, 0, pair.Value.transform.localPosition.z);
                    //使用FGUI效果后淡出效果由动态控制 
                    ShowFadeEff(pair.Value);
                    //播放显示UI音效
                    PlaySoundAndMusic(pair.Key);
                    break;
                }
            }
        }
        public static string GetUIParent(string uiName)
        {

            var obj = Util.CallMethod("Game", "getUIParent", new object[] { uiName });
            if (obj == null) return "";
            foreach (var o in obj)
            {
                if (o != null)
                    return o.ToString();
            }
            return "";
        }

        public void InitUILayerIdx()
        {
            uiLayerIdx.Add("MainParent", 100);
            uiLayerIdx.Add("MainTopParent", 200);
            uiLayerIdx.Add("PopParent", 300);
            uiLayerIdx.Add("PopTopParent", 400);
            uiLayerIdx.Add("MsgParent", 500);
            uiLayerIdx.Add("TopParent", 600);
            uiLayerIdx.Add("BaseTopParent", 700);
			uiLayerIdx.Add("GuideOrder", 800);
			uiLayerIdx.Add("ConnectOrder", 900);
		}

        public void OnLoadUIBack(GComponent uiprefab, string package, string assetName, LuaFunction func = null, LuaTable lt = null, bool isOpen = true)
        {
            //Util.Log("OnLoadUIBack:" + assetName);
            //GameObject prefab = objs[0] as GameObject;
            if (uiprefab == null) return;

            // bool canOpenMulti = false;
            // for(int i=0;i < MultiPanelView.Length;i++)
            // {
            //     if(assetName == MultiPanelView[i])
            //     {
            //         canOpenMulti = true;
            //         break;
            //     }
            // }
            // if (!canOpenMulti && UIs.ContainsKey(assetName))
            // {
            //     return;
            // }
            //
            // //临时做处理全屏自适应UI
            // Transform parent = PopParent;
            //
            // string layer = ToolsCommons.GetUIParent(assetName);
            // if(layer == "MainParent")
            // {
            //     parent = MainParent;
            // }
            // else if(layer == "MainTopParent")
            // {
            //     parent = MainTopParent;
            // }
            // else if(layer == "PopParent")
            // {
            //     parent = PopParent;
            // }
            // else if (layer == "PopTopParent")
            // {
            //     parent = PopTopParent;
            // }
            // else if (layer == "MsgParent")
            // {
            //     parent = MsgParent;
            // }
            // else if (layer == "TopParent")
            // {
            //     parent = TopParent;
            // }
            // else if(layer == "BaseTopParent")
            // {
            //     parent = BaseTopParent;
            // }
            // /*
            // Transform parent = BaseParent;
            // if (assetName == "UIBottom" || assetName == "UIHeadMenu" || assetName == "UIStory" || assetName == "UIScreenEffect" || assetName == "UICommonSet")
            // {
            //     parent = baseTopParent;
            // }
            // */
            // /*
            // if (assetName == "UILoadingBattle" || assetName == "UIRoundBattle" || name == "UIRBResult")
            //     parent = RealTimeCanvas;
            // */
            // GameObject go = Instantiate(uiprefab, parent) as GameObject;
            // go.name = assetName;
            // go.layer = LayerMask.NameToLayer("UI");
            // /*
            // if (assetName == "UILoadingBattle" || assetName == "UIRoundBattle" || name == "UIRBResult")
            //     go.layer = LayerMask.NameToLayer("Map");
            // // go.transform.SetParent(Canvas.transform);
            // */
            // go.transform.localScale = Vector3.one;
            // if (assetName != "UIBottom" && assetName != "UIHeadMenu" && assetName != "UIStory")
            // {
            //     go.transform.localPosition = Vector3.zero;
            // }
            //uiprefab.rootContainer.gameObject.AddComponent<LuaBehaviour>();
			//uiprefab.name = uiprefab.gameObjectName;
			//GRoot.inst.AddChild(uiprefab);
            var layer = GetUIParent(assetName);
            if (uiLayerIdx.ContainsKey(layer) == false)
            {
                InitUILayerIdx();
            }
            var uiIdx = uiLayerIdx[layer];
            //uiprefab.sortingOrder = uiIdx;
            if (layer != "MainTopParent" &&  layer != "MainParent")
            {
                uiLayerIdx[layer] += 1;

            }
            uiLayerOpen[assetName] = 1;
			
			//if(layer == "MainParent")
			//{
			//    uiprefab.sortingOrder = 100;
			//}
			//else if(layer == "MainTopParent")
			//{
			//   uiprefab.sortingOrder = 200;
			//}
			//else if(layer == "PopParent")
			//{
			//    uiprefab.sortingOrder = 300;
			//}
			//else if (layer == "PopTopParent")
			//{
			//    uiprefab.sortingOrder = 400;
			//}
			//else if (layer == "MsgParent")
			//{
			//    uiprefab.sortingOrder = 500;
			//}
			//else if (layer == "TopParent")
			//{
			//    uiprefab.sortingOrder = 600;
			//}
			//else if(layer == "BaseTopParent")
			//{
			//    uiprefab.sortingOrder = 700;
			//}
			if (!UIs.ContainsKey(assetName))
            {
                UIs.Add(assetName, uiprefab);
            }
            mUINameToPackageName[assetName] = package;
			var stack = new ViewStack();
			stack.Load(assetName, uiIdx, lt);
			stack.Create(uiprefab);
			AddStack(stack);
			if (isOpen)
                _OpenUI(assetName, package, uiprefab);

            if (func == null) return;
			if(isOpen)
				stack.SetState(ViewState.opened);
            if (lt != null)
                func.Call(lt, uiprefab);
            else
                func.Call(uiprefab);
			if(isOpen)
				stack.Enable();
			CallLoadDoneMethod("LuaUIMgr", "ObjectLoadFinished",uiprefab);
			//Debug.LogWarning("CreatePanel::>> " + name + " " + prefab);

		}
		
		public bool SetUILayerMask(string name,int layerMask)
		{
			var ui = GetUI(name);
			if (ui == null) return false;
			if (ui.displayObject.gameObject.layer == layerMask) return false;
			Util.SetLayerMask(ui.displayObject.gameObject, layerMask, true);
			return true;
		}
		public void CallLoadDoneMethod(string module, string func,GComponent obj)
		{
			LuaManager luaMgr = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua);
			if (luaMgr == null) return;
			LuaTable luaTable = luaMgr.GetTable(module);
			if (luaTable == null) return;
			var luaFunc = luaTable.GetLuaFunction(func);
			if (luaFunc == null) return;
			luaFunc.Call(obj);
			luaFunc.Dispose();
			luaTable.Dispose();
		}
		public void SetTopParent(GComponent obj)
        {
            obj.sortingOrder = 999;
        }

        /// </summary>
        /// <param name="name"></param>
        public void ClosePanel(string name)
        {
            var panelName = name;
            var panelObj = GRoot.inst.GetChild(panelName).asCom;
            if (panelObj == null) return;
            // Destroy(panelObj.gameObject);
            panelObj.Dispose();
            _CloseUI(name, panelObj);
        }

        public void CreatePanel(string name, string package, LuaFunction func = null, bool local = true, LuaTable lt = null, bool isOpen = true)
        {
            UIPackageResManager.Instance.LoadRes(package, name, delegate (GComponent viewGot)
            {
                if (YanhuaMMO.AppConst.UseBlackCover)
                {
                    int width = Screen.width;
                    int height = Screen.height;
                    width = Mathf.CeilToInt(width / UIContentScaler.scaleFactor);
                    height = Mathf.CeilToInt(height / UIContentScaler.scaleFactor);
                    if (viewGot != null)
                    {
                        //Debug.Log("界面资源宽====" + viewGot.sourceWidth);
                        viewGot.SetSize(viewGot.sourceWidth, height);
                        //Debug.Log("(width - viewGot.sourceWidth) / 2===" + (width - viewGot.sourceWidth) / 2);
                        viewGot.SetXY((int)((width - viewGot.sourceWidth) / 2), 0, true);
                    }
                }
                else
                {
                    viewGot.MakeFullScreen();
                }
               
                OnLoadUIBack(viewGot, package, name, func, lt, isOpen);

                FairyGUI.Controller fit = viewGot.GetController("Fit");
                if (fit != null)
                {
                    if (isNeedFit)
                    {
                        fit.selectedIndex = 1;
                        Debug.Log("fit.selectedIndex = 1");
                    }else
                    {
                        fit.selectedIndex = 0;
                        Debug.Log("fit.selectedIndex = 0");
                    }
                }
            });
        }
        private void AddPackageDependence(UIPackage package)
        {
            if (package == null) return;
            var dependence = package.dependencies;
            foreach (var d in dependence)
            {
                var name = d["name"];
                if (name.IndexOf("FUI") == -1)
                {
                    name = "FUI/" + name;
                }
                var p = UIPackage.GetById(name);
                if (p != null) continue;
                var pp = UIPackage.AddPackage(name);
                AddPackageDependence(pp);
            }
        }

        public void Pop(bool isDestroy = true, LuaFunction onFinish = null)
        {
            if (_uiQueue.Count == 0)
            {
                //Push(homeUI, null);
                return;
            }
            var name = _uiQueue[_uiQueue.Count - 1];
            _uiQueue.RemoveAt(_uiQueue.Count - 1);
            var splitName = name.Split('_');
            name = splitName[0];
            var package = splitName[1];

            CloseUI(name, package, isDestroy, onFinish);

            if (_uiQueue.Count <= 0) return;
            name = _uiQueue[_uiQueue.Count - 1];
            splitName = name.Split('_');
            name = splitName[0];
            package = splitName[1];
            ShowUI(name, package);
        }

        public void Push(string name, string package = null, LuaFunction func = null, bool local = false)
        {
            var newName = name + "_" + package;
            switch (newName)
            {
                case "hideall":
                {
                    if (_uiQueue.Contains(newName))
                    {
                        _uiQueue.Remove(newName);
                    }

                    foreach (var splitName in _uiQueue.Select(t => t.Split('_')))
                    {
                        CloseUI(splitName[0], splitName[1], false);
                    }

                    break;
                }
                case "destroyall":
                {
                    foreach (var splitName in _uiQueue.Select(t => t.Split('_')))
                    {
                        CloseUI(splitName[0], splitName[1], true);
                    }

                    break;
                }
                case "popall":
                {
                    foreach (var splitName in from t in _uiQueue where t != "hideall" && t != "destroyall" select t.Split('_'))
                    {
                        CloseUI(splitName[0], splitName[1], true);
                    }

                    _uiQueue.Clear();
                    return;
                }
                default:
                {
                    /*
                if (uiQueue.Count > 0)
                {
                    CloseUI(uiQueue[uiQueue.Count - 1], false);
                }
                */
                    if (_uiQueue.Contains(newName))
                    {
                        _uiQueue.Remove(newName);
                    }
                    _uiQueue.Add(newName);
                    ShowUI(name, package, func, local);
                    break;
                }
            }
        }


        public void CloseUI(string name, string package, bool isDestroy, LuaFunction onFinish = null)
        {
            if( _deletingUIs.Contains(name))
            {
                return;
            }
            if (UIs.ContainsKey(name))
            {
                if (UIs[name] != null)
                {
                    if( isDestroy )
                    {
                        _deletingUIs.Add(name);
                    }
					var stack = GetStack(name);
					stack.Closing();
                    FairyGUI.Transition closeTrans = UIs[name].GetTransition("Effect_JumpIn");
                    if (closeTrans != null)
                    {
                        closeTrans.invalidateBatchingEveryFrame = true;

                        closeTrans.Play(() =>
                        {
                            CloseUIReal(name, package, isDestroy, onFinish);
                        });
                    }
                    else
                    {
                        CloseUIReal(name, package, isDestroy, onFinish);
                    }
                   
                }
            }
        }

        void CloseUIReal(string name, string package, bool isDestroy, LuaFunction onFinish = null)
        {
			var stack = GetStack(name);
			if (stack != null && stack.state != ViewState.closing)
			{
				return;
			}
			stack.Closed(isDestroy);
			if (UIs.ContainsKey(name))
            {
                GetUIParent(name);
                if (UIs[name] != null)
                { 
                    _CloseUI(name, UIs[name]);

                    if (_waiting.ContainsKey(name))

                        _waiting.Remove(name);
                    if (isDestroy)
                    {
						DestroyUI(package, name);
						
					}
                    else
                    {
                        HideUI(name);
                    }
                }
				
            // if (Waiting.ContainsKey(name))
            //      Waiting.Remove(name);

            if (onFinish != null)
            //{
                onFinish.Call();
                /*if (onFinish.GetType() == typeof(LuaFunction))
                {
                    tmp = delegate (GComponent go)
                    {
                        ((LuaFunction)onFinish).Call(go);
                        ((LuaFunction)onFinish).Dispose();
                    };
                    tmp(UIs[name]);
                }*/
            }
        }
        void HideUI(string name)
        {
            var layer = GetUIParent(name);
            if (layer != "MainTopParent" && uiLayerOpen[name] != 0 && layer != "MainParent")
            {
                uiLayerIdx[layer] -= 1;
            }
            uiLayerOpen[name] = 0;
            //UIs[name].visible = false;
        }

        void DestroyUI(string packageName ,string name)
        {
            if (!UIs.ContainsKey(name)) return;

                 var layer = GetUIParent(name);
             if (layer != "MainTopParent"  && uiLayerOpen[name] != 0 && layer != "MainParent")
             {
                 uiLayerIdx[layer] -= 1;
             }
            uiLayerOpen[name] = 0;
            UIPackageResManager.Instance.UnLoadRes(packageName, name);
			RemoveStack(name);
			//UIs[name].visible = false;
            //UIs[name].Dispose();
            // Destroy(UIs[name]);
            UIs.Remove(name);
            if(_deletingUIs.Contains(name))
                _deletingUIs.Remove(name);
            //Util.CallDisposeMethod("_G", "RemoveCacheCreateUI", packageName.Replace("FUI/", "") + "/" + name);
        }

        public GComponent GetUI(string name)
        {
            return UIs.ContainsKey(name) ? UIs[name] : null;
        }

        private string GetDefaultMusic()
        {
            return _defaultMusic ?? (_defaultMusic = ToolsCommons.GetGlobalConst("12", "FunParameter"));
        }

        private void PlaySoundAndMusic(string uiName, bool check = false)
        {
            if (pauseChangeSound)
                return;
            //如果界面打开有互斥的存在，不播放音效，互斥隐藏后显示在播放
            if (CheckLocked(uiName) && check)
            {
                return;
            }

            // var sound = ToolsCommons.GetUISoundPath(uiName, "f_Sound");
            // var music = ToolsCommons.GetUISoundPath(uiName, "f_Music");
            // if (!string.IsNullOrEmpty(sound))
            // {
            //     SoundManager.Instance.Play("sound/common/" + sound, null);
            // }

            // if (string.IsNullOrEmpty(music)) return;
            // //Debug.Log("-----------playmusic------" + music + "-------" + uiName + "-----" + Time.frameCount);
            // if (UIs != null && UIs.ContainsKey("UIRoundBattle") && !UIs["UIRoundBattle"].visible && uiName != "UIRoundBattle") return;
            // SoundManager.Instance.PlayBG("sound/bg/" + music, true);
        }

        public void ShowUI(string name, string package, LuaFunction onFinish = null, bool local = false, LuaTable lt = null)
        {

			//Util.Log("open ui name" + name);
			try { 
				if (name == "")
				{
					return;
				}
				//PlaySoundAndMusic(name,true);  --没有资源暂时注释
				if (UIs.ContainsKey(name))
				{

					//UIs[name].visible = true;
					var layer = GetUIParent(name);
					int order = uiLayerIdx[layer];
					//UIs[name].sortingOrder = uiLayerIdx[layer];
					if (layer != "MainTopParent" &&  layer != "MainParent" && uiLayerOpen[name] != 1)
					{
						uiLayerIdx[layer] += 1;
					}
					uiLayerOpen[name] = 1;
					var stack = GetStack(name);
					stack.Create(order);
					AddStack(stack);

					if (onFinish != null)
					{
						stack.SetState(ViewState.opened);
						if (lt != null)
							onFinish.Call(lt, UIs[name]);
						else
							onFinish.Call(UIs[name]);

						onFinish.Dispose();
						stack.Enable();
						CallLoadDoneMethod("LuaUIMgr", "ObjectLoadFinished", UIs[name]);
					}
					_OpenUI(name, package, UIs[name]);
				}
				else
				{
					CreatePanel(name, package, onFinish, local, lt);
				}
			}catch(Exception e)
			{
				Debug.LogError(e.Message);
			}

		}

        public bool IsOpen(string name)
        {
			var stack = GetStack(name);
			if (stack != null && (stack.state == ViewState.opened || stack.state == ViewState.closing))
			{
				return true;
			}
			return false;
            //return UIs.ContainsKey(name) && UIs[name].visible;
        }

        public int OpenUICount()
        {
            return UIs.Count(ui => ui.Value.visible);
        }

        public static void ShowFadeEff(GComponent uipanel, Action callback = null)
        {
            //todo fgui 播放动效以及调用回调

            // CanvasGroup cvsgroup = uipanel.GetComponent<CanvasGroup>();
            // if(cvsgroup == null)
            //     cvsgroup = uipanel.gameObject.AddComponent<CanvasGroup>();
            // uipanel.localScale = new Vector3(0.2f, 0.2f, 0.2f);
            // Sequence sq = DOTween.Sequence();
            // sq.Append(uipanel.DOScale(new Vector3(1, 1, 1), 0.3f).SetEase(Ease.OutBack));
            //
            // if (cvsgroup != null)
            // {
            //     cvsgroup.alpha = 0.3f;
            //     cvsgroup.DOFade(1, 0.3f);
            // }
            // sq.onComplete = () =>
            // {
            //     callback?.Invoke();
            // };
        }

        //public void HideAllExcept(string[] names)
        //{
        //    foreach(string key in UIs.Keys)
        //    {
        //        bool find = false;
        //        for(int i =0;i< names.Length; i++)
        //        {
        //            if(key == names[i])
        //            {
        //                find = true;
        //                break;
        //            }
        //        }

        //        if (!find)
        //        {

        //        }
        //    }
        //}

        //获取最上层显示的弹板
        public void CheckApexPanel()
        {
            if (UIs.Count == 0)
                return;

            List<string> _showPanelList = new List<string>();
            foreach(var item in UIs)
            {
                if(item.Value.visible)
                {
                    _showPanelList.Add(item.Key);
                }
            }
            _showPanelList.Sort((panelName1,panelName2) =>  -(UIs[panelName1].sortingOrder).CompareTo(UIs[panelName2].sortingOrder));
            string _showPanels = string.Join(",", _showPanelList.ToArray());
            Util.CallMethod("AudioManager", "PlayBGM", _showPanels);
        }

		private class ViewStack
		{
			public int order;
			public ViewState state;
			public string name;
			public GComponent go;
			public LuaTable luaView;
			public bool isEnable = false;
			public void SetState(ViewState state)
			{
				this.state = state;
			}
			public void Load(string name, int order, LuaTable luaView)
			{
				this.name = name;
				this.order = order;
				this.luaView = luaView;
				state = ViewState.loading;
			}
			public void Create(int order,bool isFirst = false)
			{
				this.order = order;
				if (go != null)
				{
					go.sortingOrder = order;
					go.visible = false;
				}
			}
			//first create
			public void Create(GComponent go)
			{
				if (go != null)
				{
					this.go = go;
					go.name = go.gameObjectName;
					GRoot.inst.AddChild(go);
				}
				Create(order, true);
			}
			public void Enable()
			{
				if (go != null)
					go.visible = true;
				if (luaView != null)
				{
					if (!isEnable)
					{
						isEnable = true;
						var f = luaView.GetLuaFunction("Enable");
						if (f != null)
						{
							f.Call(luaView);
							f.Dispose();
						}
					}
				}
				else
				{
					//兼容旧系统
					var b = go.displayObject.gameObject.GetComponent<LuaBehaviour>();
					if (b == null)
						go.displayObject.gameObject.AddComponent<LuaBehaviour>();
				}
			}
			public void Closing()
			{
				state = ViewState.closing;
			}
			public void Closed(bool isDestroy)
			{
				state = ViewState.close;
				if (luaView != null)
				{
					if (isEnable)
					{
						isEnable = false;
						var f = luaView.GetLuaFunction("Disable");
						if (f != null)
						{
							f.Call(luaView);
							f.Dispose();
						}
					}
				}
				if (isDestroy)
				{
					if (luaView != null)
					{
						var f = luaView.GetLuaFunction("Destroy");
						if (f != null)
						{
							f.Call(luaView);
							f.Dispose();
						}
						f = luaView.GetLuaFunction("OnDestroyAfter");
						if (f != null)
						{
							f.Call(luaView);
							f.Dispose();
						}
						luaView.Dispose();
						luaView = null;
					}
					else
					{
						//兼容旧系统
						var b = go.displayObject.gameObject.GetComponent<LuaBehaviour>();
						if (b != null)
							DestroyImmediate(b);
					}
					go.Dispose();
					go = null;
				}
				else
					go.visible = false;

			}
		}
	}
	
}